#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
# Reason-GPL: import-scapy
import argparse
import random
import socket

from scapy.all import Ether, IP, TCP, Raw, get_if_hwaddr, get_if_list, sendp

def pick_iface():
    ifs = get_if_list()
    # 优先选择 *-eth0，其次包含 eth0 的接口
    for i in ifs:
        if i.endswith("-eth0"):
            return i
    for i in ifs:
        if "eth0" in i:
            return i
    raise SystemExit("Cannot find an eth0-like interface")

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("dst", help="目的地址（推荐：h1→10.0.0.1，h2→10.0.0.2）")
    ap.add_argument("message", help="负载字符串")
    ap.add_argument("--src", help="源地址（建议：h1=10.0.1.1，h2=10.0.2.2）")
    ap.add_argument("--iface", help="出接口（默认自动选 *-eth0）")
    ap.add_argument("--count", type=int, default=10, help="发送报文个数，默认10")
    ap.add_argument("--interval", type=float, default=0.05, help="报文间隔秒，默认0.05")
    ap.add_argument("--l2dst", help="以太网目的MAC；若省略则使用广播（避免ARP依赖）")
    ap.add_argument("--syn", action="store_true", help="只发送SYN（默认发送携带数据）")
    args = ap.parse_args()

    iface = args.iface or pick_iface()
    l2dst = args.l2dst or "ff:ff:ff:ff:ff:ff"
    src_mac = get_if_hwaddr(iface)


    dst_ip = socket.gethostbyname(args.dst)

    ip = IP(dst=dst_ip)
    if args.src:
        ip.src = args.src

    sport = random.randint(49152, 65535)
    flags = "S" if args.syn else "PA"
    tcp = TCP(dport=1234, sport=sport, flags=flags)

    payload = Raw(load=args.message.encode("utf-8"))
    frame = Ether(src=src_mac, dst=l2dst) / ip / tcp / payload

    frame.show()

    sendp(frame, iface=iface, count=args.count, inter=args.interval, verbose=False)
    print(f"[OK] sent {args.count} pkts on {iface} to {dst_ip} (L2 dst {l2dst})")

if __name__ == "__main__":
    main()
